package top.fwpsl.redis;

/**
 * set 操作
 *
 * @auther: 风戏fw
 * @date: 2020/11/21
 */
public interface IJedisSetClient {

    /**
     * 将一个或多个 member 元素加入到集合 key 当中，已经存在于集合的 member 元素将被忽略。
     * 假如 key 不存在，则创建一个只包含 member 元素作成员的集合。
     * 当 key 不是集合类型时，返回一个错误
     * <p>
     * 时间复杂度: O(N), N是被添加的元素的数量。
     *
     * @param key
     * @param values
     * @return 被添加到集合中的新元素的数量，不包括被忽略的元素
     */
    long sadd(String key, Object... values);

    /**
     * 返回集合 key 的基数(集合中元素的数量)
     * <p>
     * 时间复杂度: O(1)
     *
     * @param key
     * @return 集合的基数; 当 key不存在时，返回 0 。
     */
    long scard(String key);

    /**
     * 返回一个集合的全部成员，该集合是所有给定集合之间的差集。
     * 不存在的 key 被视为空集
     * <p>
     * 时间复杂度： O(N)， N 是所有给定集合的成员数量之和
     *
     * @param keys
     * @return 交集成员的列表
     */
    Object[] sdiff(String... keys);

    /**
     * 这个命令的作用和 SDIFF 类似，但它将结果保存到 destination 集合，而不是简单地返回结果集。
     * 如果 destination 集合已经存在，则将其覆盖。
     * destination 可以是 key 本身。
     * <p>
     * 时间复杂度: O(N)， N是所有给定集合的成员数量之和
     *
     * @param destination
     * @param keys
     * @return 结果集中的元素数量
     */
    long sdiffstore(String destination, String... keys);

    /**
     * 返回一个集合的全部成员，该集合是所有给定集合的交集。
     * 不存在的 key 被视为空集。
     * 当给定集合当中有一个空集时，结果也为空集(根据集合运算定律)
     * <p>
     * 时间复杂度: O(N * M)， N 为给定集合当中基数最小的集合， M 为给定集合的个数
     *
     * @param keys
     * @return 交集成员的列表
     */
    Object[] sinter(String... keys);

    /**
     * 这个命令类似于 SINTER 命令，但它将结果保存到 destination 集合，而不是简单地返回结果集。
     * 如果 destination 集合已经存在，则将其覆盖。
     * destination 可以是 key 本身
     * <p>
     * 时间复杂度: O(N * M)， N 为给定集合当中基数最小的集合， M 为给定集合的个数
     *
     * @param destination
     * @param keys
     * @return 结果集中的成员数量
     */
    long sinterstore(String destination, String... keys);

    /**
     * 判断 member 元素是否集合 key 的成员
     * <p>
     * 时间复杂度: O(1)
     *
     * @param key
     * @param member
     * @return 如果 member 元素是集合的成员，返回 1; 如果 member 元素不是集合的成员，或 key 不存在，返回 0
     */
    byte sismembers(String key, Object member);

    /**
     * 返回集合 key 中的所有成员; 不存在的 key 被视为空集合。
     * <p>
     * 时间复杂度: O(N), N为集合的基数
     *
     * @param key
     * @return 集合中的所有成员
     */
    Object[] smember(String key);

    /**
     * 将 member 元素从 source 集合移动到 destination 集合
     * <p>
     * 时间复杂度: O(1)
     *
     * @param source
     * @param destination
     * @param member
     * @return 如果 member 元素被成功移除，返回 1 。
     * 如果 member 元素不是 source 集合的成员，并且没有任何操作对 destination 集合执行，那么返回 0
     */
    byte smove(String source, String destination, Object member);

    /**
     * 移除并返回集合中的一个随机元素
     * <p>
     * 时间复杂度：O(1)
     *
     * @param key
     * @return 被移除的随机元素。 当 key 不存在或 key 是空集时，返回 nil 。
     */
    Object spop(String key);

    /**
     * 如果命令执行时，只提供了 key 参数，那么返回集合中的一个随机元素
     * <p>
     * SRANDMEMBER 命令接受可选的 count 参数：
     * 如果 count 为正数，且小于集合基数，那么命令返回一个包含 count 个元素的数组，数组中的元素各不相同。
     * > 如果 count 大于等于集合基数，那么返回整个集合。
     * 如果 count 为负数，那么命令返回一个数组，数组中的元素可能会重复出现多次，而数组的长度为 count 的绝对值。
     *
     * @param key
     * @param count
     * @return
     */
    Object[] srandmember(String key, int count);

    /**
     * 移除集合 key 中的一个或多个 member 元素，不存在的 member 元素会被忽略。
     * 当 key 不是集合类型，返回一个错误。
     * <p>
     * 时间复杂度：O(N), N为给定 member 元素的数量
     *
     * @param key
     * @param members
     * @return 被成功移除的元素的数量，不包括被忽略的元素
     */
    int srem(String key, Object... members);

    /**
     * 返回一个集合的全部成员，该集合是所有给定集合的并集。
     * 不存在的 key 被视为空集
     * <p>
     * 时间复杂度：O(N), N是所有给定集合的成员数量之和
     * @param key
     * @return 并集成员的列表
     */
    Object[] sunion(String... key);

    /**
     * 它将结果保存到 destination 集合，而不是简单地返回结果集。
     * 如果 destination 已经存在，则将其覆盖。
     * destination 可以是 key 本身。
     * <p>
     * 时间复杂度：O(N), N是所有给定集合的成员数量之和
     * @param destination
     * @param keys
     * @return 结果集中的元素数量
     */
    int sunionstore(String destination, String... keys);

}
